﻿using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.Linq;

namespace CommonUtils
{
    public static class PoiUtil
    {
        public static void SaveTo(this ISheet sheet, string path)
        {
            var stream = FileUtil.GetCreateStream(path);
            sheet.Workbook.Write(stream);
            stream.Close();
        }

        public static ISheet CreateSheet(string path)
        {
            var extension = FileUtil.GetExtension(path);
            ISheet sheet = null;
            if (extension == ".xlsx")
                sheet = new XSSFWorkbook().CreateSheet();
            if (extension == ".xls")
                sheet = new HSSFWorkbook().CreateSheet();
            return sheet;
        }

        public static ISheet GetOrCreateSheet(string path)
        {
            var extension = FileUtil.GetExtension(path);
            if (FileUtil.Exists(path))
            {
                var stream = FileUtil.GetReadStream(path);
                ISheet sheet = null;
                if (extension == ".xlsx")
                    sheet = new XSSFWorkbook(stream).GetSheetAt(0);
                if (extension == ".xls")
                    sheet = new HSSFWorkbook(stream).GetSheetAt(0);
                stream.Close();
                return sheet;
            }
            return CreateSheet(path);
        }

        public static bool HasRow(this ISheet sheet)
        => sheet.PhysicalNumberOfRows > 0;

        public static bool IsEmpty(this ISheet sheet)
        => !sheet.HasRow();

        public static IRow Fill(this IRow row, object[] values)
        {
            for (var index = 0; index < values.Length; index++)
                row.CreateCell(index).SetCellValue(values[index].ToStringEx());
            return row;
        }

        public static IRow CreateNewRow(this ISheet sheet, params object[] values)
        => (sheet.IsEmpty() ? sheet.CreateRow(0) : sheet.CreateRow(sheet.LastRowNum + 1)).Fill(values);

        public static string[] GetValues(this IRow row)
        => row.Cells.Select(m => m.StringCellValue).ToArray();

        public static bool HasCell(this IRow row)
        => row.PhysicalNumberOfCells > 0;

        public static bool IsEmpty(this IRow row)
        => !row.HasCell();

        public static ICell CreateNewCell(this IRow row)
        => row.IsEmpty() ? row.CreateCell(0) : row.CreateCell(row.LastCellNum);

        public static void AddCell(this IRow row, object value)
        => row.CreateNewCell().SetCellValue(value.ToString());

        public static void AddDoubleCell(this IRow row, object value)
        => row.CreateNewCell().SetCellValue(value.ToDouble());
    }
}
